<template>
    <div class="sidebar" v-loading="loading" :style="{ width: sidebarWidth + 'px' }"
        :class="{ 'below-min': sidebarWidth < minWidth }">
        <div class="sidebar-header">
            <div class="header-content">
                <button class="back-btn" @click="$emit('navigate-home')">
                    <span class="back-icon">
                        <IconHome />
                    </span>
                </button>
                <div class="project-info">
                    <div class="project-icon">
                        <img src="@/assets/projectIcon.jpg" alt="项目图标">
                    </div>
                    <div class="project-details">
                        <h3 class="project-name">{{ projectStore.getProjectInfo().name || '-' }}</h3>
                        <p class="project-desc">API接口文档</p>
                    </div>
                </div>
            </div>
        </div>
        <!-- 搜索和操作区域 -->
        <div class="search-actions-bar">
            <div class="action-buttons">
                <el-button @click="handleAddNode(null)" class="add-module-btn" title="新建模块"
                    v-permission="'project:manage:api:create'">
                    <IconAdd />
                </el-button>
            </div>
            <div class="search-container">
                <el-input v-model="searchKeyword" placeholder="搜索api接口" class="search-input" clearable
                    @input="handleSearchInput" @clear="handleSearchClear">
                    <template #suffix>
                        <el-icon v-if="isSearching" class="is-loading">
                            <Loading />
                        </el-icon>
                    </template>
                </el-input>
            </div>
            <el-button type="primary" @click="handleSearch" :disabled="!searchKeyword.trim()">
                搜索
            </el-button>
        </div>

        <!-- 搜索结果区域 -->
        <div v-if="showResult" class="search-results" v-loading="isSearching">
            <div class="search-results-header">
                <span>API搜索结果 ({{ searchResults.length }})</span>
            </div>
            <div class="search-results-list">
                <div v-for="result in searchResults" :key="result.id" class="search-result-item"
                    @click="handleSearchResultClick(result)">
                    <span class="api-method" :class="getMethodClass(result.method)">
                        {{ result.method || '-' }}
                    </span>
                    <span class="result-name">{{ result.name }}</span>
                    <span class="result-module"> {{ result.module_name }} </span>
                </div>
            </div>
        </div>

        <div class="sidebar-content" v-else>
            <!-- 递归渲染模块树 -->
            <a-tree v-model:expandedKeys="expandedKeys" v-model:selectedKeys="selectedKeys"
                v-model:loadedKeys="loadedKeys" :load-data="onLoadData" :tree-data="treeData"
                :field-names="{ children: 'children', title: 'name', key: 'key' }">
                <template #title="{ dataRef }">
                    <div class="custom-node"
                        :class="{ 'is-api': dataRef.type === 'api', 'is-module': dataRef.type === 'module' }"
                        @click="handleNodeClick(dataRef)">
                        <div class="node-content">
                            <!-- 展开/收起按钮 - 仅模块显示 -->
                            <span v-if="dataRef.type === 'module'" class="expand-icon"
                                :class="{ 'expanded': expandedKeys.includes(dataRef.key) }">
                                <IconExpand class="icon-expand" />
                            </span>

                            <!-- API方法标签 -->
                            <span v-if="dataRef.type === 'api'" class="api-method"
                                :class="getMethodClass(dataRef.method)">
                                {{ dataRef.method || '-' }}
                            </span>

                            <!-- 节点名称 -->
                            <span class="node-name">{{ dataRef.name }}</span>

                            <!-- 模块操作按钮（仅悬浮时显示） -->
                            <div v-if="dataRef.type === 'module'" class="node-actions" @click.stop>
                                <button class="icon-btn" @click="handleAddNode(dataRef)" title="新增"
                                    v-permission="'project:manage:api:create'">
                                    <IconAdd />
                                </button>
                                <button class="icon-btn" @click="handleEditNode(dataRef)" title="编辑"
                                    v-permission="'project:manage:api:create'">
                                    <IconEdit />
                                </button>
                                <button class="icon-btn" @click="handleDeleteNode(dataRef)" title="删除"
                                    v-permission="'project:manage:api:create'">
                                    <IconDelete />
                                </button>
                            </div>
                        </div>
                    </div>
                </template>
            </a-tree>
        </div>

        <!-- 个人信息区域 -->
        <div class="user-info">
            <div class="user-avatar">
                <img src="@/assets/user.webp" alt="用户头像">
                <div class="user-status online"></div>
            </div>
            <div class="user-details">
                <div class="user-name">{{ projectStore.getUsefProjectInfo()?.nickname || '-' }}</div>
                <div class="user-role">{{ projectStore.getUsefProjectInfo()?.role_name || '-' }}</div>
            </div>
            <el-button v-permission="'project:manage:center'" type="primary"
                @click="$emit('dashboard-home')">项目管理</el-button>
        </div>
    </div>

    <el-dialog v-model="showHandleModuleDialog" :title="titleText" width="450" :show-close="false"
        :close-on-click-modal="false">
        <el-form>
            <el-form-item label="模块名称" :label-width="formLabelWidth">
                <el-input v-model="moduleName" autocomplete="off" />
            </el-form-item>
        </el-form>
        <template #footer>
            <div class="dialog-footer">
                <el-button @click="() => { showHandleModuleDialog = false; moduleName = ''; }">取消</el-button>
                <el-button type="primary" @click="handleSubmitModule">
                    确定
                </el-button>
            </div>
        </template>
    </el-dialog>

    <el-dialog v-model="showSelectDialog" title="选择添加类型" width="400" :show-close="false" :close-on-click-modal="false">
        <div class="select-dialog-content">
            <p class="dialog-desc">请选择要添加的内容类型</p>
            <div class="select-buttons">
                <el-button type="primary" @click="handleSelectModule" class="select-btn">
                    <i class="iconfont icon-folder"></i>
                    添加模块
                </el-button>
                <el-button type="success" @click="handleSelectApi" class="select-btn">
                    <i class="iconfont icon-api"></i>
                    添加API
                </el-button>
            </div>
        </div>
        <template #footer>
            <div class="dialog-footer">
                <el-button @click="showSelectDialog = false">取消</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { useProjectStore } from '@/store/modules/project';
import { onMounted, ref, nextTick, computed, inject } from 'vue';
import { getTopLevelModules, getModuleChildren, getShortestTreeById, AddModule, editModule, deleteModuleApi, searchProjectApis } from '@/common/apis/project/index.ts';
import { ElMessage } from 'element-plus';
import { debounce } from 'lodash';
import { Loading } from '@element-plus/icons-vue';

const route = useRoute();
const projectStore = useProjectStore();

// 响应式状态
const expandedKeys = ref([]);
const selectedKeys = ref([]);
const loadedKeys = ref([]);
const treeData = ref([]);
const showHandleModuleDialog = ref(false);
const moduleName = ref('');
const currentModuleInfo = ref(null);
const currentParentNode = ref([]);
const showSelectDialog = ref(false);
const currentSelectModule = ref(null);
const modeModuleType = ref('add');
const currentEditModule = ref(null);
const loading = ref(false);
const searchKeyword = ref('');
const searchResults = ref([]);
const isSearching = ref(false);
const showResult = ref(false);

// 计算属性
const projectId = computed(() => Number(route.params.id));
const formLabelWidth = '80px';
const titleText = computed(() => {
    return modeModuleType.value === 'add' ? '添加模块' : '编辑模块';
});

// 搜索API函数（只搜索API接口）
const searchApi = async (keyword: string) => {
    try {
        // 这里需要调用后端搜索API，只搜索API接口
        const { data } = await searchProjectApis({ projectId: projectId.value, keyword });
        return data || [];
    } catch (error) {
        return [];
    }
};

// 防抖搜索函数
const debouncedSearch = debounce(async (keyword: string) => {
    if (!keyword.trim()) {
        searchResults.value = [];
        return;
    }
    isSearching.value = true;
    try {
        const results = await searchApi(keyword);
        searchResults.value = results;
    } finally {
        isSearching.value = false;
    }
}, 300);

// 处理搜索输入
const handleSearchInput = (value: string) => {
    searchKeyword.value = value;
    showResult.value = value.trim().length > 0;
    debouncedSearch(value);
};

// 处理搜索清除
const handleSearchClear = () => {
    showResult.value = false;
    searchKeyword.value = '';
    searchResults.value = [];
};

// 处理搜索按钮点击
const handleSearch = () => {
    if (searchKeyword.value.trim()) {
        debouncedSearch(searchKeyword.value);
        showResult.value = true;
    } else {
        showResult.value = false;
    }
};

// 清除搜索结果
const clearSearchResults = () => {
    showResult.value = false;
    searchResults.value = [];
    searchKeyword.value = '';
};

// 处理搜索结果点击（只处理API）
const handleSearchResultClick = async (result: any) => {
    loading.value = true;
    showResult.value = false;
    try {
        clearSearchResults();

        // // 先进行路由跳转
        // await router.replace({
        //     path: `/project/${route.params.id}/api/${result.id}`,
        //     query: { ...route.query, mode: 'view' }
        // });

        // 然后进行侧边栏定位（使用搜索模式，强制重新加载）
        await refreshAndLocateNode({
            id: result.id,
            isReload: true,
            type: 'api',
            refresh: true
        });
    } catch (error) {
    } finally {
        loading.value = false;
    }
};

defineProps({
    sidebarWidth: {
        type: Number,
        default: 380
    },
    minWidth: {
        type: Number,
        default: 320
    },
    interceptApiClick: {
        type: Function,
        default: () => true
    },
    interceptModuleClick: {
        type: Function,
        default: () => true
    }
});

const emit = defineEmits(['add-item', 'navigate-home', 'dashboard-home', 'click-api', 'add-api']);

// 处理节点点击
const handleNodeClick = (dataRef) => {
    if (dataRef.type === 'module') {
        toggleNodeExpansion(dataRef.key);
    } else if (dataRef.type === 'api') {
        emit('click-api', dataRef.id);
    }
};

// 切换节点展开状态
const toggleNodeExpansion = (key) => {
    const index = expandedKeys.value.indexOf(key);
    if (index > -1) {
        expandedKeys.value.splice(index, 1);
    } else {
        expandedKeys.value.push(key);
    }
};

// 添加模块
const handleSubmitModule = async () => {
    if (!moduleName.value.trim()) {
        ElMessage.warning('请输入模块名称');
        return;
    }
    loading.value = true;
    try {
        const params = {
            id: modeModuleType.value === 'edit' ? currentEditModule.value.id : null,
            project_id: projectId.value,
            parent_id: modeModuleType.value === 'edit' ? currentEditModule.value.parent_id : currentModuleInfo.value?.id,
            name: moduleName.value.trim()
        };

        const _method = modeModuleType.value === 'add' ? AddModule : editModule;

        const res = await _method(params);
        ElMessage.success(res.message);
        await refreshAndLocateNode({ id: modeModuleType.value === 'edit' ? currentEditModule.value.id : res.data.id, type: 'module' });
        resetModuleDialog();
    } catch (error) {
        console.error('添加模块失败:', error);
        ElMessage.error('添加模块失败');
    } finally {
        loading.value = false;
    }
};

// 重置模块对话框
const resetModuleDialog = () => {
    moduleName.value = '';
    modeModuleType.value = 'add';
    showHandleModuleDialog.value = false;
    currentModuleInfo.value = null;
};

// 等待指定节点加载出子节点，或被判定为叶子节点
const waitForNodeChildrenOrLeaf = (node) => {
    return new Promise(resolve => {
        const check = () => {
            if ((node.children && node.children.length > 0) || node.isLeaf === true) {
                resolve();
            } else {
                setTimeout(check, 100);
            }
        };
        check();
    });
};

// 处理添加节点
const handleAddNode = async (dataRef) => {
    if (!dataRef) { handleSelectModule(); return; }
    // 1) 若未展开，先展开，触发懒加载（已展开则不做折叠，避免闪烁）
    if (!expandedKeys.value.includes(dataRef.key)) {
        expandedKeys.value.push(dataRef.key);
        await nextTick();
    }

    // 2) 等待该节点完成子节点加载（有子/无子都会很快落定）。
    // 若已展开但 children 仍旧是旧数据（缓存导致），强制重载一次
    const beforeCount = Array.isArray(dataRef.children) ? dataRef.children.length : 0;
    await waitForNodeChildrenOrLeaf(dataRef);
    const afterCount = Array.isArray(dataRef.children) ? dataRef.children.length : 0;
    if (beforeCount === afterCount && beforeCount > 0) {
        await forceReloadNode(dataRef);
    }

    // 3) 根据结果决定行为
    const children = Array.isArray(dataRef.children) ? dataRef.children : [];
    if (children.length === 0) {
        // 无子节点：弹出选择对话框
        currentSelectModule.value = dataRef;
        showSelectDialog.value = true;
        return;
    }

    // 有子节点：根据首个子节点类型决定默认行为
    const firstChildType = children[0]?.type;
    if (firstChildType === 'module') {
        modeModuleType.value = 'add';
        showHandleModuleDialog.value = true;
        currentModuleInfo.value = dataRef;

    } else {
        emit('add-api', dataRef);
    }
};

// 强制重载某个模块节点（清除缓存并重新加载，不折叠，避免闪烁）
const forceReloadNode = async (node) => {
    // 清掉懒加载缓存
    loadedKeys.value = loadedKeys.value.filter(k => k !== node.key);
    // 直接请求并覆盖 children，避免先折叠再展开
    await reloadNodeData(node);
};

// 处理选择添加模块
const handleSelectModule = () => {
    showSelectDialog.value = false;
    showHandleModuleDialog.value = true;
    currentModuleInfo.value = currentSelectModule.value;
    currentSelectModule.value = null;
};

// 处理选择添加API
const handleSelectApi = () => {
    showSelectDialog.value = false;
    emit('add-api', currentSelectModule.value);
    currentSelectModule.value = null;
};

// 处理编辑节点
const handleEditNode = (dataRef) => {
    modeModuleType.value = 'edit';
    moduleName.value = dataRef.name;
    showHandleModuleDialog.value = true;
    currentEditModule.value = dataRef;
};

// 处理删除节点
const handleDeleteNode = (dataRef) => {
    ElMessageBox.confirm(
        `确定要删除 "${dataRef.name}" 模块吗,对应下面的所有接口和模块都将被删除`,
        '提示',
        {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
            type: 'warning',
        }
    )
        .then(async () => {
            const res = await deleteModuleApi({ id: dataRef.id, projectId: dataRef.project_id });
            ElMessage.success({ message: `${res.message}` });
            // 触发sidebar树刷新
            refreshAndLocateNode({ id: res.data, isReload: true, type: 'module' });
        })
        .catch(() => {
        });
};

// 懒加载数据
const onLoadData = async (treeNode) => {
    const { dataRef } = treeNode;

    // API节点不需要加载子数据
    if (dataRef.type === 'api') return;

    dataRef.loading = true;

    try {
        const { data } = await getModuleChildren({
            projectId: projectId.value,
            id: dataRef.id
        });

        if (data?.length > 0) {
            dataRef.children = data;
            // 触发响应式更新
            treeData.value = [...treeData.value];
        } else {
            dataRef.isLeaf = true;
        }
    } catch (error) {
        showErrorMessage('加载子节点失败，请检查网络设置');
    } finally {
        dataRef.loading = false;
    }
};

// 递归查找节点
const findNodeById = (nodes, id) => {
    if (!Array.isArray(nodes)) return null;

    for (const node of nodes) {
        if (node.id === id) return node;

        if (node.children?.length) {
            const found = findNodeById(node.children, id);
            if (found) return found;
        }
    }

    return null;
};

// 刷新并定位节点
const refreshAndLocateNode = async ({ id, isReload = true, type = 'api', refresh = false }) => {
    try {
        const { data } = await getShortestTreeById({
            id,
            projectId: projectId.value,
            type
        });
        if (data && !refresh) {
            // 普通点击模式
            await expandPathByClicking(data, id, isReload, type);
        } else {
            // 搜索模式，强制重新加载
            await expandPathBySearch(data, id);
        }
    } catch (error) {
        console.error('刷新并定位节点失败:', error);
    }
};

// 按路径展开节点
const expandPathByClicking = async (pathArray, targetId, isReload = true, type = 'api') => {
    currentParentNode.value = [];
    const reloadId = (() => {
        if (type === 'api') {
            return pathArray.length >= 1
                ? pathArray[pathArray.length - 1].id
                : null;
        } else {
            return pathArray.length >= 2
                ? pathArray[pathArray.length - 2].id
                : null;
        }
    })();
    if (reloadId === null) {
        // 如果长度不够，获取顶层模块
        const { data } = await getTopLevelModules({ projectId: projectId.value });
        treeData.value = data || [];
        currentParentNode.value = treeData.value;
        await selectAndScrollToTarget(targetId);
        return;
    }

    try {
        // 确保顶层数据已加载
        await ensureTopLevelData();

        currentParentNode.value = treeData.value;
        const pathLength = type === 'api' ? pathArray.length : pathArray.length - 1;

        // 按路径展开每个节点
        for (let i = 0; i < pathLength; i++) {
            const nodeId = pathArray[i].id;
            const node = currentParentNode.value.find(item => item.id === nodeId);

            if (!node) {
                continue;
            }

            // 如果需要重新加载该节点
            if (reloadId === nodeId && isReload) {
                await reloadNodeData(node);
            } else {
                // 展开节点并等待子数据加载
                await expandNodeAndWait(node);
            }
        }

        // 选中目标节点并滚动到视图
        await selectAndScrollToTarget(targetId);

    } catch (error) {
    }
};

// 不使用缓存，重新加载并且定位节点，搜索功能
const expandPathBySearch = async (pathArray, targetId) => {
    currentParentNode.value = [];
    try {
        // 确保顶层数据已加载
        await ensureTopLevelData();

        currentParentNode.value = treeData.value;
        const pathLength = pathArray.length;

        // 按路径展开每个节点
        for (let i = 0; i < pathLength; i++) {
            const nodeId = pathArray[i].id;
            const node = currentParentNode.value.find(item => item.id === nodeId);
            if (!node) {
                console.warn(`节点未找到: ${nodeId}`);
                continue;
            }
            //重新加载该节点
            await reloadNodeData(node);
            // 展开节点并等待子数据加载
            await expandNodeAndWait(node);

            // 如果是最后一个节点（API节点），确保其父节点被正确设置
            if (i === pathLength - 1) {
                currentParentNode.value = node.children || [];
            }
        }

        // 选中目标节点并滚动到视图
        await selectAndScrollToTarget(targetId);
        emit('click-api', targetId);
    } catch (error) {
    }
};

// 确保顶层数据已加载
const ensureTopLevelData = async () => {
    if (treeData.value.length === 0) {
        const { data } = await getTopLevelModules({ projectId: projectId.value });
        treeData.value = data || [];
    }
};

// 重新加载节点数据
const reloadNodeData = async (node) => {
    const { data } = await getModuleChildren({
        projectId: projectId.value,
        id: node.id
    });

    const targetNode = findNodeById(treeData.value, node.id);
    if (targetNode) {
        targetNode.children = data || [];
        treeData.value = [...treeData.value];
        currentParentNode.value = targetNode.children;
    }
};

// 展开节点并等待子数据
const expandNodeAndWait = async (node) => {
    if (!expandedKeys.value.includes(node.key)) {
        expandedKeys.value.push(node.key);
        // 等待子数据加载完成
        await waitForChildrenData(node);
    }
    currentParentNode.value = node.children;
};

// 等待子数据加载
const waitForChildrenData = (node) => {
    return new Promise(resolve => {
        const checkChildren = () => {
            if (node.children?.length > 0) {
                resolve();
            } else {
                setTimeout(checkChildren, 100);
            }
        };
        checkChildren();
    });
};

// 选中目标并滚动到视图
const selectAndScrollToTarget = async (targetId) => {
    const targetNode = currentParentNode.value.find(item => item.id === targetId);

    if (targetNode?.key) {
        selectedKeys.value = [targetNode.key];
        // 滚动到选中节点
        await nextTick();
        const selectedElement = document.querySelector('.ant-tree-node-selected');
        if (selectedElement) {
            selectedElement.scrollIntoView({
                behavior: 'smooth',
                block: 'center'
            });
        } else {
            console.warn('未找到目标元素');
        }
    } else {
        console.warn('未找到目标节点:', { targetId, currentParentNode: currentParentNode.value });
    }
};

// 获取API方法的样式类
const getMethodClass = (method) => {
    const methodMap = {
        'GET': 'get',
        'POST': 'post',
        'PUT': 'put',
        'DELETE': 'delete',
    };
    return methodMap[method?.toUpperCase()] || '';
};

// 创建防抖的错误提示函数
const showErrorMessage = debounce((message: string) => {
    ElMessage.error(message);
}, 300);

// 组件挂载时加载数据
onMounted(async () => {
    try {
        await ensureTopLevelData();
    } catch (error) {
        ElMessage.error('加载数据失败，请检查网络设置');
    }
});

defineExpose({
    refreshAndLocateNode
});
</script>

<style lang="less" scoped>
// 左侧导航栏
.sidebar {
    background: var(--card-bg);
    border-right: 1px solid var(--border-light);
    display: flex;
    flex-direction: column;
    box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    transition: width 0.1s ease;

    // 低于最小宽度时的样式
    &.below-min {
        border-right-color: var(--warning-color);
        box-shadow: 2px 0 8px rgba(255, 193, 7, 0.2);
    }

    // 侧边栏头部
    .sidebar-header {
        padding: 20px;
        border-bottom: 1px solid var(--border-light);
        position: relative;
        overflow: hidden;
        flex-shrink: 0;
        background: linear-gradient(135deg, transparent 0%, var(--primary-light) 100%);
        color: var(--text-primary);

        &:hover {
            .back-btn {
                opacity: 1;
                transform: translateX(0);
            }

            .project-info {
                transform: translateX(48px);
            }
        }

        // 头部内容
        .header-content {
            display: flex;
            align-items: center;
            gap: 12px;
            position: relative;
        }

        // 返回按钮
        .back-btn {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 36px;
            height: 36px;
            background: var(--primary-color);
            border: 1px solid var(--border-light);
            border-radius: 50%;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.3s ease;
            backdrop-filter: blur(10px);
            flex-shrink: 0;
            opacity: 0;
            transform: translateX(-20px);
            position: absolute;
            left: 0;
            z-index: 2;
            color: var(--bg-primary);

            &:hover {
                background: var(--primary-light);
                border-color: var(--primary-light);
                box-shadow: var(--shadow-medium);
            }

            &:active {
                background: var(--primary-color);
                box-shadow: var(--shadow-light);
            }
        }

        .back-icon {
            font-weight: bold;
            color: inherit;
        }

        // 项目信息
        .project-info {
            display: flex;
            align-items: center;
            gap: 12px;
            flex: 1;
            min-width: 0;
            transform: translateX(0);
            transition: transform 0.3s ease;
        }

        // 项目图标
        .project-icon {
            width: 40px;
            height: 40px;
            border-radius: 8px;
            overflow: hidden;
            border: 2px solid rgba(255, 255, 255, 0.3);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
            flex-shrink: 0;

            img {
                width: 100%;
                height: 100%;
                object-fit: cover;
            }
        }

        // 项目详情
        .project-details {
            flex: 1;
            min-width: 0;
        }

        .project-name {
            margin: 0 0 2px 0;
            font-size: 14px;
            font-weight: 600;
            color: var(--text-primary);
            line-height: 1.3;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .project-desc {
            margin: 0;
            font-size: 11px;
            color: var(--text-primary);
            line-height: 1.3;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
    }

    // 侧边栏内容
    .sidebar-content {
        flex: 1;
        overflow-y: auto;
        overflow-x: hidden;
        padding: 0;
        scrollbar-width: none;
        -ms-overflow-style: none;
        padding: 8px;

        :deep(.ant-tree-treenode) {
            width: 100% !important;
            padding: 0;
            background: var(--bg-tertiary);
        }

        :deep(.ant-tree-node-content-wrapper) {
            width: 100% !important;

        }

        :deep(.ant-tree-node-content-wrapper-open) {
            width: 100% !important;
        }

        :deep(.ant-tree-node-content-wrapper-close) {
            width: 100% !important;
        }

        :deep(.ant-tree-node-selected) {
            width: 100% !important;
            background: var(--card-bg);
        }

        &::-webkit-scrollbar {
            display: none;
        }

        // 隐藏默认的展开按钮
        :deep(.ant-tree-switcher) {
            display: none !important;
        }

        // 确保树节点内容正确显示
        :deep(.ant-tree) {
            width: 100% !important;
        }

        :deep(.ant-tree-node) {
            width: 100%;
        }

        // 自定义树节点样式
        .custom-node {
            display: flex;
            align-items: center;
            width: 100%;
            cursor: pointer;
            transition: all 0.2s ease;
            user-select: none;
            position: relative;
            border: none;
            min-height: 36px;
            border-radius: 6px;
            margin: 2px 0;

            // 模块节点样式
            &.is-module {
                padding: 8px 16px 8px 8px;

                &:hover {
                    background: var(--hover-bg);
                    border: 2px solid var(--hover-border);
                    box-shadow: var(--hover-shadow);
                    transform: translateX(4px);
                }

                .expand-icon {
                    margin-right: 4px;
                    transition: transform 0.2s ease;
                    transform: rotate(-90deg);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 18px;
                    height: 18px;
                    color: var(--primary-color);

                    &.expanded {
                        transform: rotate(0deg);
                    }

                    svg {
                        width: 16px;
                        height: 16px;
                        fill: currentColor;
                    }
                }
            }

            // API节点样式
            &.is-api {
                padding: 6px 12px;
                margin: 1px 0;

                &:hover {
                    background: var(--hover-bg);
                    border: 2px solid var(--hover-border);
                    box-shadow: var(--hover-shadow);
                    transform: translateX(4px);
                    border-left: 4px solid var(--primary-color);
                }
            }

            .node-content {
                display: flex;
                align-items: center;
                width: 100%;
                position: relative;

                .icon-expand {
                    color: var(--text-primary);
                }
            }

            .api-method {
                display: inline-block;
                padding: 2px 6px;
                border-radius: 4px;
                font-size: 10px;
                font-weight: 600;
                text-transform: uppercase;
                margin-right: 8px;
                min-width: 36px;
                text-align: center;
                flex-shrink: 0;
                line-height: 1.4;

                &.get {
                    background: var(--api-get-bg);
                    color: var(--api-get-color);
                    border: 1px solid var(--api-get-color);
                }

                &.post {
                    background: var(--api-post-bg);
                    color: var(--api-post-color);
                    border: 1px solid var(--api-post-color);
                }

                &.put {
                    background: var(--api-put-bg);
                    color: var(--api-put-color);
                    border: 1px solid var(--api-put-color);
                }

                &.delete {
                    background: var(--api-delete-bg);
                    color: var(--api-delete-color);
                    border: 1px solid var(--api-delete-color);
                }

                &.patch {
                    background: var(--primary-glass);
                    color: var(--primary-color);
                    border: 1px solid var(--primary-color);
                }
            }

            .node-name {
                flex: 1;
                font-size: 13px;
                color: var(--text-primary);
                font-weight: 500;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                line-height: 1.4;
            }

            // 右侧操作按钮组（仅悬浮时出现）
            .node-actions {
                position: absolute;
                right: 0;
                top: 50%;
                transform: translateY(-50%) translateX(8px);
                display: inline-flex;
                gap: 6px;
                opacity: 0;
                pointer-events: none;
                transition: opacity 0.18s ease, transform 0.2s ease;
            }

            &:hover .node-actions {
                opacity: 1;
                transform: translateY(-50%) translateX(0);
                pointer-events: auto;
            }

            .icon-btn {
                display: inline-flex;
                align-items: center;
                justify-content: center;
                width: 24px;
                height: 24px;
                border: 1px solid var(--border-color);
                border-radius: 6px;
                background: var(--bg-primary);
                color: var(--text-secondary);
                cursor: pointer;
                transition: all 0.2s ease;
                padding: 0;
                box-shadow: var(--shadow-light);

                :deep(svg),
                :deep(i) {
                    width: 14px;
                    height: 14px;
                    color: var(--text-secondary);
                    fill: var(--text-secondary);
                }

                &:hover {
                    background: var(--primary-color);
                    color: var(--bg-primary);
                    border-color: var(--primary-color);
                    transform: translateY(-1px);
                    box-shadow: var(--hover-shadow);

                    :deep(svg),
                    :deep(i) {
                        color: var(--bg-primary);
                        fill: var(--bg-primary);
                    }
                }

                &:active {
                    box-shadow: var(--shadow-light);
                }

                // 编辑按钮特殊样式
                &:first-child:hover {
                    background: var(--info-color);
                    border-color: var(--info-color);
                }

                // 删除按钮特殊样式
                &:last-child:hover {
                    background: var(--error-color);
                    border-color: var(--error-color);
                }
            }
        }

        // 选中状态样式
        .ant-tree-node-selected .custom-node {
            background: var(--card-bg);
            border: 2px solid var(--primary-color);
            box-shadow: var(--shadow-medium);
            transform: translateX(4px);
        }

        // 展开状态样式
        .ant-tree-switcher {
            display: none; // 隐藏默认的展开按钮
        }
    }

    // 个人信息区域
    .user-info {
        margin-top: auto; // 推到底部
        padding: 16px;
        border-top: 1px solid var(--border-light);
        background: var(--bg-secondary);
        display: flex;
        align-items: center;
        gap: 12px;
        flex-shrink: 0; // 防止被压缩

        // 用户头像
        .user-avatar {
            position: relative;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            overflow: hidden;
            border: 2px solid var(--border-light);
            flex-shrink: 0;

            img {
                width: 100%;
                height: 100%;
                object-fit: cover;
            }

            // 用户状态
            .user-status {
                position: absolute;
                bottom: 2px;
                right: 2px;
                width: 12px;
                height: 12px;
                border-radius: 50%;
                border: 2px solid var(--card-bg);

                &.online {
                    background: var(--success-color);
                }

                &.offline {
                    background: var(--text-secondary);
                }

                &.away {
                    background: var(--warning-color);
                }
            }
        }

        // 用户详情
        .user-details {
            flex: 1;
            min-width: 0; // 允许收缩

            .user-name {
                font-size: 14px;
                font-weight: 600;
                color: var(--text-primary);
                margin-bottom: 2px;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }

            .user-role {
                font-size: 12px;
                color: var(--text-secondary);
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }
        }

        // 响应式设计
        @media (max-width: 768px) {
            padding: 12px;
            gap: 8px;

            .user-avatar {
                width: 32px;
                height: 32px;
            }

            .user-details {
                .user-name {
                    font-size: 13px;
                }

                .user-role {
                    font-size: 11px;
                }
            }
        }
    }
}

// 搜索和操作栏
.search-actions-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-light);
    flex-shrink: 0;

    .search-container {
        flex: 1;

        .search-input {
            :deep(.el-input__wrapper) {
                border-radius: 6px;
                box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
                transition: all 0.3s ease;

                &:hover {
                    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
                }

                &.is-focus {
                    box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
                }
            }

            :deep(.el-input__prefix) {
                color: var(--text-secondary);
            }
        }
    }

    .action-buttons {
        display: flex;
        gap: 6px;

        .add-module-btn {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 32px;
            height: 32px;
            padding: 0;
            border-radius: 6px;
            border: 1px solid var(--border-color);
            background: var(--bg-primary);
            transition: all 0.2s ease;
            box-shadow: var(--shadow-light);
            color: var(--text-secondary);

            i,
            svg {
                font-size: 14px;
                color: var(--text-secondary);
                fill: var(--text-secondary);
            }

            &:hover {
                background: var(--primary-color);
                border-color: var(--primary-color);
                color: var(--bg-primary);
                transform: translateY(-1px);
                box-shadow: var(--hover-shadow);

                i,
                svg {
                    color: var(--bg-primary);
                    fill: var(--bg-primary);
                }
            }

            &:active {
                box-shadow: var(--shadow-light);
            }
        }
    }
}

// 搜索结果区域
.search-results {
    margin: 8px 0;
    border: 1px solid var(--border-light);
    border-radius: 6px;
    background: var(--bg-primary);

    .search-results-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 8px 12px;
        border-bottom: 1px solid var(--border-light);
        background: var(--bg-secondary);
        font-size: 12px;
        color: var(--text-secondary);
    }

    .search-results-list {
        max-height: 200px;
        overflow-y: auto;

        .api-method {
            display: inline-block;
            padding: 2px 6px;
            border-radius: 4px;
            font-size: 10px;
            font-weight: 600;
            text-transform: uppercase;
            margin-right: 8px;
            min-width: 36px;
            text-align: center;
            flex-shrink: 0;
            line-height: 1.4;

            &.get {
                background: var(--api-get-bg);
                color: var(--api-get-color);
                border: 1px solid var(--api-get-color);
            }

            &.post {
                background: var(--api-post-bg);
                color: var(--api-post-color);
                border: 1px solid var(--api-post-color);
            }

            &.put {
                background: var(--api-put-bg);
                color: var(--api-put-color);
                border: 1px solid var(--api-put-color);
            }

            &.delete {
                background: var(--api-delete-bg);
                color: var(--api-delete-color);
                border: 1px solid var(--api-delete-color);
            }

            &.patch {
                background: var(--primary-glass);
                color: var(--primary-color);
                border: 1px solid var(--primary-color);
            }
        }
    }

    .search-result-item {
        display: flex;
        align-items: center;
        padding: 8px 12px;
        cursor: pointer;
        border-bottom: 1px solid var(--border-light);
        transition: background-color 0.2s ease;

        &:hover {
            background: var(--hover-bg);
        }

        &:last-child {
            border-bottom: none;
        }

        .api-method {
            margin-right: 8px;
            padding: 2px 6px;
            border-radius: 3px;
            font-size: 11px;
            font-weight: 500;
            min-width: 40px;
            text-align: center;

            &.GET {
                background: #e8f5e8;
                color: #2e7d32;
            }

            &.POST {
                background: #e3f2fd;
                color: #1976d2;
            }

            &.PUT {
                background: #fff3e0;
                color: #f57c00;
            }

            &.DELETE {
                background: #ffebee;
                color: #d32f2f;
            }
        }

        .result-name {
            flex: 1;
            font-size: 13px;
            color: var(--text-primary);
            margin-right: 8px;
        }

        .result-module {
            font-size: 12px;
            color: var(--text-secondary);
        }
    }
}

// 搜索输入框样式优化
.search-container {
    .search-input {
        :deep(.el-input__wrapper) {
            transition: all 0.3s ease;

            &:hover {
                box-shadow: 0 0 0 1px var(--primary-light);
            }

            &.is-focus {
                box-shadow: 0 0 0 2px var(--primary-light);
            }
        }
    }
}

// 选择对话框样式
.select-dialog-content {
    text-align: center;
    padding: 20px 0;

    .dialog-desc {
        margin: 0 0 24px 0;
        color: var(--text-secondary);
        font-size: 14px;
    }

    .select-buttons {
        display: flex;
        gap: 16px;
        justify-content: center;

        .select-btn {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 12px 24px;
            font-size: 14px;
            font-weight: 500;
            border-radius: 8px;
            transition: all 0.2s ease;
            background: var(--bg-primary);
            border: 1px solid var(--border-color);
            color: var(--text-primary);

            i {
                font-size: 16px;
                color: var(--text-secondary);
            }

            &:hover {
                background: var(--primary-color);
                color: var(--bg-primary);
                transform: translateY(-1px);
                box-shadow: var(--hover-shadow);

                i {
                    color: var(--bg-primary);
                }
            }

            &:active {
                box-shadow: var(--shadow-light);
            }
        }
    }
}

.dialog-footer {
    text-align: center;
}
</style>
